﻿using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using WorkFlowCore.Authorization;
using WorkFlowCore.Authorization.JWT;
using WorkFlowCore.Common.Tracers;
using WorkFlowCore.Plugins;

namespace WorkFlowCore.Common.Authorization.JWT
{
    public class AuthorizationMiddleware
    {
        private readonly RequestDelegate next;

        public AuthorizationMiddleware(RequestDelegate next)
        {
            this.next = next;
        }


        public async Task Invoke(HttpContext context, JWTAuthenticationManager jWTAuthenticationManager)
        {
            var activity = WorkflowActivitySource.Source?.StartActivity("AuthorizationMiddleware");

           
            // 检查请求的控制器和操作方法是否允许匿名访问
            var endpoint = context.GetEndpoint();

            if (endpoint == null ||endpoint?.Metadata.GetMetadata<IAllowAnonymous>() != null)
            {
                // 如果允许匿名访问，直接跳过身份验证
                await next(context);
            }
            else
            {
                var pluginid = context.GetContextParameter( "pluginid");
                var appid = context.GetContextParameter( "appid");
                var accessToken = context.GetContextParameter("access_token");
                var thirdpartauthorization = context.GetContextParameter("thirdpartauthorization");

                if (!string.IsNullOrEmpty(accessToken))
                {
                    context.Request.Headers["authorization"] = $"Bearer {accessToken}";
                }

                // 执行身份验证
                var authenticateResult = await context.AuthenticateAsync();
                var tryautologinTag = "tryautologin";
                if (!authenticateResult.Succeeded)
                {
                    var hasTryLogin = context.Request.QueryString.HasValue ?
                        context.Request.QueryString.Value.ToString().Contains(tryautologinTag)
                        : false;

                    //尝试登录过就不管了
                    if (hasTryLogin)
                    {
                        // 认证不通过，设置 401 状态码并结束请求
                        context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                        return;
                    }
                    else
                    {
                        
                        
                        if (string.IsNullOrWhiteSpace(thirdpartauthorization))
                        {
                            thirdpartauthorization = context.Request.Query["access_token"].ToString();
                        }

                        accessToken = context.Request.Headers["authorization"].ToString();

                        activity?.AddTag("appid", appid ?? "null");
                        activity?.AddTag("authorization", accessToken ?? "null");
                        activity?.AddTag("thirdpartauthorization", thirdpartauthorization ?? "null");


                        if (!JWTAuthenticationOptions.AuthenticationEnacted)
                        {
                            context.Request.Headers["authorization"] = $"Bearer {jWTAuthenticationManager.GenerateDefaultToken()}";
                        }
                        else
                        {
                            var validOutput = jWTAuthenticationManager.CheckCustomizationVerify(new VerifyInput { Context = context, AccessToken = accessToken, AppId = appid, ThirdPartToken = thirdpartauthorization }, pluginid);
                            
                            if(validOutput?.IsValid??false)
                            {
                                accessToken = jWTAuthenticationManager.Login(validOutput.User, validOutput.Claims);
                            }
                        }

                        var queryStrings = new Dictionary<string,string>();
                        foreach (var item in context.Request.Query)
                        {
                            queryStrings.Add(item.Key,item.Value);
                        }

                        queryStrings["access_token"] = accessToken;
                        queryStrings[tryautologinTag] = "";
                        context.Response.Redirect(context.Request.Path + "?" + string.Join("&", queryStrings.Select(q=>$"{q.Key}={q.Value}")),false,true);
                        return;
                    }
                }

                // 认证通过，继续处理请求
                await next(context);
            }

        }
    }
}
